# pragma once

# include "cpp_tools_Headers.h"

namespace cpp_tools
{
    /// @brief 多线程安全管理器
    /// @tparam T 需要管理的数据类型
    template<typename T>
    class mtDataManager
    {
    protected:
        std::shared_mutex mtx;

        T data;

    public:
        mtDataManager(){};
        
        template <typename... Args>
        mtDataManager(Args&&... args) : data(std::forward<Args>(args)...) {}

        /// @brief 只读访问者
        class Accessor_read
        {
        protected:
            mtDataManager &mtDataManager_;
            std::shared_lock<std::shared_mutex> read_lock;

        public:
            Accessor_read(mtDataManager &that)
                :mtDataManager_(that), read_lock(that.mtx)
            {};

            ~Accessor_read(){};

            /// @brief 只读访问
            /// @return 管理数据的指针
            const T* access() const
            {
                return &mtDataManager_.data;
            }

            Accessor_read(const Accessor_read&) = delete;

            Accessor_read& operator=(const Accessor_read&) = delete;
        };

        /// @brief 读写访问者
        class Accessor_write
        {
        protected:
            mtDataManager &mtDataManager_;
            std::unique_lock<std::shared_mutex> write_lock;

        public:
            Accessor_write(mtDataManager &that)
                :mtDataManager_(that), write_lock(that.mtx)
            {};

            ~Accessor_write(){};
            
            /// @brief 读写访问
            /// @return 管理数据的指针
            T* access()
            {
                return &mtDataManager_.data;
            }

            Accessor_write(const Accessor_write&) = delete;

            Accessor_write& operator=(const Accessor_write&) = delete;
        };

        /// @brief 获取只读访问权限
        /// @return 
        Accessor_read read()
        {
            return {*this};
        }

        /// @brief 获取读写访问权限
        /// @return 
        Accessor_write write()
        {
            return {*this};
        }
    };
    
} // namespace cpp_tools

